package concreto.neuronio;

import java.util.Random;

import comportamento.neuronio.INeuronioAbstrato;
import comportamento.neuronio.IPerceptron;

public class PerceptronSimples extends NeuronioGenerico implements IPerceptron {

    public PerceptronSimples(double limiar) {
	super(limiar);
	this.selecionarFuncaoAtivacao(INeuronioAbstrato.ATIVACAO_DEGRAU);
	this.bk = this.gerarValorRandomico();
	
    }

    public void treinar(double[][] treino, double[] saidaDesejada) {

	/* quantidade de padrões apresentados */
	int padroes = treino[0].length;
	/* quantidade de entradas */
	int entradas = treino.length;//Linhas

	super.geraPesosConexoes(padroes);
	
	/* vetor para calculo do erro de cada padrão de entrada */
	double[] err = new double[entradas];

	double E = 1;
	double alfa = 1;
	int t = 0;
	int max_it = 1000;

	/* treina o algoritmo */
	while(t < max_it & E > 0){

	    for(int j = 0; j < entradas ; j++){

		/* cálculo o erro para o padrão apresentado */
		err[j] = saidaDesejada[j] - this.estimular(treino[j]); 

		/* atualiza os pesos */
		for(int i = 0; i < padroes ; i++){
		    this.wk[i] = this.wk[i] + alfa * err[j] * this.estimulos[i];
		}
		
		/* atualiza o bias */
		this.bk = this.bk + alfa * err[j];
	    }

	    E = this.erroQuadratico(err);
	    t++;
	}

    }

    /* (non-Javadoc)
     * @see concreto.neuronio.NeuronioGenerico#ponderarEstimulos(double[])
     */
    @Override 
    public double[] ponderarEstimulos(double[] estimulos) {
	
	this.estimulos = estimulos;
	int quantidadeEntradas = estimulos.length;
	
	double[] resultados = new double[quantidadeEntradas]; 
	//geraPesosConexoes(quantidadeEntradas);
	
	for(int i = 0; i < quantidadeEntradas; i ++) {
	    resultados[i] = estimulos[i] * this.wk[i];
	}
	
	return resultados;
    }

    /* (non-Javadoc)
     * @see comportamento.neuronio.NeuronioAbstrato#gerarValorRandomico()
     */
    @Override
    public double gerarValorRandomico() {

	return new Random().nextDouble();
    }

    /* (non-Javadoc)
     * @see concreto.neuronio.NeuronioMP#calcularUk(double[])
     */
    @Override
    public void calcularUk(double[] vetorPesosConexao) {
	
	super.calcularUk(vetorPesosConexao);
	this.uk = this.uk + this.bk;
    }

}
